/*
 * Copyright (c) 2023 fred
 * Licensed under the Apache License,Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import List from '@ohos.util.List'

export class ArrayUtils {

  public static binarySearch(a:any[] | List<any> | string,key:any,fromIndex:number = 0,toIndex:number = a.length):number {
    ArrayUtils.rangeCheck(a.length,fromIndex,toIndex)
    return ArrayUtils.binarySearch0(a,fromIndex,toIndex,key)
  }

  static rangeCheck(arrayLength:number,fromIndex:number,toIndex:number) {
    if (fromIndex > toIndex) {
      throw Error(`fromIndex(${fromIndex}) > toIndex(${toIndex})`)
    }
    if (fromIndex < 0) {
      throw Error(`Array index out of range: ${fromIndex}`)
    }
    if (toIndex > arrayLength) {
      throw Error(`Array index out of range: ${toIndex}`)
    }
  }

  static areArraysEqual(array1:any[],array2:any[]):boolean {
    if (array1 === undefined || array1 === null || array2 === undefined || array1 === null) {
      return false
    }
    if (array1.length !== array2.length) {
      return false
    }
    return array1.every((value,index) => value === array2[index])
  }

  private static binarySearch0(a:any[]|List<any> | string,fromIndex:number,toIndex:number,key:any):number {
    let low = fromIndex
    let high = toIndex - 1
    while (low <= high) {
      let mid = low + Math.floor((high - low) / 2)
      if (a[mid] === key) {
        return mid
      }
      if (a[mid] < key) {
        low = mid + 1;
      } else {
        high = mid - 1;
      }
    }
    // key not found.
    return -(low + 1)
  }


}
